package com.teacher.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.teacher.common.CommonResult;
import com.teacher.common.JwtTokenUtil;
import com.teacher.pojo.dto.flow.ApproveFlowDto;
import com.teacher.pojo.dto.flow.MyApproveGetDto;
import com.teacher.pojo.entity.*;
import com.teacher.mapper.FlowMapper;
import com.teacher.pojo.enums.FlowApproveType;
import com.teacher.pojo.enums.FlowType;
import com.teacher.pojo.vo.flow.FlowApproveDetailsVo;
import com.teacher.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 流程总表 服务实现类
 * </p>
 *
 * @author zfm
 * @since 2021-08-03
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class FlowServiceImpl extends ServiceImpl<FlowMapper, Flow> implements IFlowService {

    @Autowired
    private ISerialNumberService iSerialNumberService;

    @Autowired
    private IFlowApproveService iFlowApproveService;

    @Autowired
    private IPerStudentService iPerStudentService;

    @Autowired
    private IMoralEducationTaskService iMoralEducationTaskService;

    @Autowired
    private IMoralEducationService iMoralEducationService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private HttpServletRequest httpServletRequest;

    @Autowired
    private IJobTaskService iJobTaskService;

    @Autowired
    private IJobService iJobService;

    @Autowired
    private IGoodThingsTaskService iGoodThingsTaskService;

    @Autowired
    private IGoodThingsService iGoodThingsService;

    @Autowired
    private IPublicWelfareActivitiesTaskService iPublicWelfareActivitiesTaskService;

    @Autowired
    private IPublicWelfareActivitiesService iPublicWelfareActivitiesService;

    @Autowired
    private ICertificateTaskService iCertificateTaskService;

    @Autowired
    private ICertificateService iCertificateService;

    @Autowired
    private IInnovativeUndertakingTaskService iInnovativeUndertakingTaskService;

    @Autowired
    private IInnovativeUndertakingService iInnovativeUndertakingService;

    @Autowired
    private ICourseContestsTaskService iCourseContestsTaskService;

    @Autowired
    private ICourseContestsService iCourseContestsService;

    @Autowired
    private ICulturalActivitiesRewardTaskService iCulturalActivitiesRewardTaskService;

    @Autowired
    private ICulturalActivitiesRewardService iCulturalActivitiesRewardService;

    @Autowired
    private ICulturalTransmissionTaskService iCulturalTransmissionTaskService;

    @Autowired
    private ICulturalTransmissionService iCulturalTransmissionService;

    /**
     * 发起流程
     *
     * @param applyKey
     * @param currentKey
     * @param name
     * @return
     */
    @Override
    public Long createFlow(String applyKey, String currentKey, String name) {
        Flow flow = new Flow();
        flow.setApplyUsername(applyKey);
        flow.setStatus(FlowApproveType.WAIT.getCode());
        flow.setType(FlowType.getCodeByName(name));
        flow.setCurrentApproveUsername(currentKey);
        String serialNumber = iSerialNumberService.getSerialNumber();
        flow.setSerialNumber(serialNumber);
        String title = "";
        PerStudent userApply = iPerStudentService.getOne(new QueryWrapper<PerStudent>().lambda()
                .eq(PerStudent::getStudentKey, applyKey).last("limit 1"));
        title = userApply.getName() + "-" + serialNumber + "-" + name;
        flow.setTitle(title);
        if (this.save(flow)) {
            // 启动流程
            FlowApprove flowApprove = new FlowApprove();
            flowApprove.setApplyUsername(applyKey);
            flowApprove.setApproveUsername(currentKey);
            flowApprove.setStatus(FlowApproveType.WAIT.getCode());
            flowApprove.setFlowId(flow.getId());
            if (iFlowApproveService.save(flowApprove)) {
                return flow.getId();
            }
        }
        return null;
    }

    /**
     * 重新发起流程
     *
     * @param flowId
     * @return
     */
    @Override
    public CommonResult<String> reStart(Long flowId) {

        Flow flow = this.getById(flowId);
        if (flow == null) {
            return CommonResult.failed("流程不存在");
        }
        if (!flow.getStatus().equals(FlowApproveType.BACK_UPDATE.getCode())) {
            return CommonResult.failed("当前状态不可更新信息");
        }
        flow.setStatus(FlowApproveType.WAIT.getCode());
        FlowApprove flowApprove = iFlowApproveService.getOne(new QueryWrapper<FlowApprove>().lambda()
                .eq(FlowApprove::getFlowId, flowId).last("limit 1"));
        flowApprove.setId(null);
        flowApprove.setStatus(FlowApproveType.WAIT.getCode());
        flowApprove.setOpinion("");
        flowApprove.setUpdateTime(null);
        flowApprove.setCreateTime(null);
        // 当前审批人换成上一节点审批人
        flow.setCurrentApproveUsername(flowApprove.getApproveUsername());

        if (iFlowApproveService.save(flowApprove)) {
            flow.setCurrentApproveUsername(flowApprove.getApproveUsername());
            this.updateById(flow);
            return CommonResult.success("ok");
        }
        return null;
    }

    /**
     * 删除流程
     *
     * @param flowId
     * @return
     */
    @Override
    public CommonResult<String> del(Long flowId) {
        Flow flow = this.getById(flowId);
        if (flow == null) {
            return CommonResult.failed("流程不存在");
        }
        if (!flow.getStatus().equals(FlowApproveType.WAIT.getCode())) {
            return CommonResult.failed("当前状态不能删除");
        }
        // 删除流程审批总表
        this.removeById(flowId);
        // 删除流程审批子表
        iFlowApproveService.remove(new QueryWrapper<FlowApprove>().lambda()
                .eq(FlowApprove::getFlowId, flowId));
        if (flow.getType().equals(FlowType.MORAL_EDUCATION.getCode())) {
            // 德育素质
            return delMoralEducation(flowId);
        } else if (flow.getType().equals(FlowType.JOB.getCode())) {
            // 学生干部任职
            return delJob(flowId);
        } else if (flow.getType().equals(FlowType.GOOD_THINGS.getCode())) {
            // 好人好事
            return delGoodThings(flowId);
        } else if (flow.getType().equals(FlowType.PUBLIC_WELFARE_ACTIVITIES.getCode())) {
            // 公益活动
            return delPublicWelfareActivities(flowId);
        } else if (flow.getType().equals(FlowType.CERTIFICATE.getCode())) {
            // 证书申请
            return delCertificate(flowId);
        } else if (flow.getType().equals(FlowType.INNOVATIVE_UNDERTAKING.getCode())) {
            // 创新创业认定
            return delInnovativeUndertaking(flowId);
        } else if (flow.getType().equals(FlowType.COURSE_CONTESTS.getCode())) {
            // 学科竞赛
            return delCourseContests(flowId);
        } else if (flow.getType().equals(FlowType.CULTURAL_ACTIVITIES_REWARD.getCode())) {
            // 文艺活动
            return delCulturalActivitiesReward(flowId);
        } else if (flow.getType().equals(FlowType.CULTURAL_TRANSMISSION.getCode())) {
            // 文化传播
            return delCulturalTransmission(flowId);
        }
        return null;
    }

    /**
     * 删除文化传播
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delCulturalTransmission(Long flowId) {
        if (iCulturalTransmissionTaskService.remove(new QueryWrapper<CulturalTransmissionTask>().lambda()
                .eq(CulturalTransmissionTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除文艺活动
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delCulturalActivitiesReward(Long flowId) {
        if (iCulturalActivitiesRewardTaskService.remove(new QueryWrapper<CulturalActivitiesRewardTask>().lambda()
                .eq(CulturalActivitiesRewardTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除学科竞赛
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delCourseContests(Long flowId) {
        if (iCourseContestsTaskService.remove(new QueryWrapper<CourseContestsTask>().lambda()
                .eq(CourseContestsTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除创新创业认定
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delInnovativeUndertaking(Long flowId) {
        if (iInnovativeUndertakingTaskService.remove(new QueryWrapper<InnovativeUndertakingTask>().lambda()
                .eq(InnovativeUndertakingTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除证书申请
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delCertificate(Long flowId) {
        if (iCertificateTaskService.remove(new QueryWrapper<CertificateTask>().lambda()
                .eq(CertificateTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 公益活动
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delPublicWelfareActivities(Comparable<Long> flowId) {
        if (iPublicWelfareActivitiesTaskService.remove(new QueryWrapper<PublicWelfareActivitiesTask>().lambda()
                .eq(PublicWelfareActivitiesTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除好人好事
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delGoodThings(Long flowId) {
        if (iGoodThingsTaskService.remove(new QueryWrapper<GoodThingsTask>().lambda()
                .eq(GoodThingsTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 删除学生干部任职
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delJob(Long flowId) {
        if (iJobTaskService.remove(new QueryWrapper<JobTask>().lambda()
                .eq(JobTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }

    /**
     * 审批流程
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<String> approve(ApproveFlowDto dto) {
        Flow flow = this.getById(dto.getId());
        if (flow == null) {
            return CommonResult.failed("流程不存在");
        }
        if (!flow.getCurrentApproveUsername().equals(jwtTokenUtil.getUsernameByRequest(httpServletRequest))) {
            return CommonResult.failed("不是当前审批人");
        }

        if (!flow.getStatus().equals(FlowApproveType.WAIT.getCode())) {
            return CommonResult.failed("当前流程异常，请刷新重试");
        }

        // 总审批表
        flow.setStatus(dto.getStatus());
        if (dto.getStatus().equals(FlowApproveType.BACK_UPDATE.getCode())) {
            // 如果是退回，当前审批人换成申请人
            flow.setCurrentApproveUsername(flow.getApplyUsername());
        }
        this.updateById(flow);
        FlowApprove flowApproveOp = new FlowApprove();
        flowApproveOp.setOpinion(dto.getOpinion());
        flowApproveOp.setStatus(flow.getStatus());
        iFlowApproveService.update(flowApproveOp, new QueryWrapper<FlowApprove>().lambda()
                .eq(FlowApprove::getFlowId, flow.getId())
                .eq(FlowApprove::getApproveUsername, jwtTokenUtil.getUsernameByRequest(httpServletRequest))
                .eq(FlowApprove::getStatus, FlowApproveType.WAIT.getCode()));

        // 同意
        if (dto.getStatus().equals(FlowApproveType.PASS.getCode())) {
            // 德育素质
            if (flow.getType().equals(FlowType.MORAL_EDUCATION.getCode())) {
                return agreeMoralEducation(flow);
            }
            // 学生干部任职
            if (flow.getType().equals(FlowType.JOB.getCode())) {
                return agreeJob(flow);
            }
            // 好人好事
            if (flow.getType().equals(FlowType.GOOD_THINGS.getCode())) {
                return agreeGoodThings(flow);
            }
            // 公益活动
            if (flow.getType().equals(FlowType.PUBLIC_WELFARE_ACTIVITIES.getCode())) {
                return agreePublicWelfareActivities(flow);
            }
            // 证书申请
            if (flow.getType().equals(FlowType.CERTIFICATE.getCode())) {
                return agreeCertificate(flow);
            }
            // 创新创业
            if (flow.getType().equals(FlowType.INNOVATIVE_UNDERTAKING.getCode())) {
                return agreeInnovativeUndertaking(flow);
            }
            // 学科竞赛
            if (flow.getType().equals(FlowType.COURSE_CONTESTS.getCode())) {
                return agreeCourseContests(flow);
            }
            // 文艺活动
            if (flow.getType().equals(FlowType.CULTURAL_ACTIVITIES_REWARD.getCode())) {
                return agreeCulturalActivitiesReward(flow);
            }
            // 文化传播
            if (flow.getType().equals(FlowType.CULTURAL_TRANSMISSION.getCode())) {
                return agreeCulturalTransmission(flow);
            }
        }
        return CommonResult.success("审批成功");
    }

    /**
     * 同意文化传播
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeCulturalTransmission(Flow flow) {
        CulturalTransmissionTask culturalTransmissionTask = iCulturalTransmissionTaskService.getOne(new QueryWrapper<CulturalTransmissionTask>().lambda()
                .eq(CulturalTransmissionTask::getFlowId, flow.getId()).last("limit 1"));
        CulturalTransmission culturalTransmission = new CulturalTransmission();
        BeanUtils.copyProperties(culturalTransmissionTask, culturalTransmission);
        if (iCulturalTransmissionService.save(culturalTransmission)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意文艺活动
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeCulturalActivitiesReward(Flow flow) {
        CulturalActivitiesRewardTask culturalActivitiesRewardTask = iCulturalActivitiesRewardTaskService.getOne(new QueryWrapper<CulturalActivitiesRewardTask>().lambda()
                .eq(CulturalActivitiesRewardTask::getFlowId, flow.getId()).last("limit 1"));
        CulturalActivitiesReward culturalActivitiesReward = new CulturalActivitiesReward();
        BeanUtils.copyProperties(culturalActivitiesRewardTask, culturalActivitiesReward);
        if (iCulturalActivitiesRewardService.save(culturalActivitiesReward)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意学科竞赛
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeCourseContests(Flow flow) {
        CourseContestsTask courseContestsTask = iCourseContestsTaskService.getOne(new QueryWrapper<CourseContestsTask>().lambda()
                .eq(CourseContestsTask::getFlowId, flow.getId()).last("limit 1"));
        CourseContests courseContests = new CourseContests();
        BeanUtils.copyProperties(courseContestsTask, courseContests);
        if (iCourseContestsService.save(courseContests)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意创新创业
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeInnovativeUndertaking(Flow flow) {
        InnovativeUndertakingTask innovativeUndertakingTask = iInnovativeUndertakingTaskService.getOne(new QueryWrapper<InnovativeUndertakingTask>().lambda()
                .eq(InnovativeUndertakingTask::getFlowId, flow.getId()).last("limit 1"));
        InnovativeUndertaking innovativeUndertaking = new InnovativeUndertaking();
        BeanUtils.copyProperties(innovativeUndertakingTask, innovativeUndertaking);
        if (iInnovativeUndertakingService.save(innovativeUndertaking)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意证书申请
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeCertificate(Flow flow) {
        CertificateTask certificateTask = iCertificateTaskService.getOne(new QueryWrapper<CertificateTask>().lambda()
                .eq(CertificateTask::getFlowId, flow.getId()).last("limit 1"));
        Certificate certificate = new Certificate();
        BeanUtils.copyProperties(certificateTask, certificate);
        if (iCertificateService.save(certificate)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意公益活动
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreePublicWelfareActivities(Flow flow) {
        PublicWelfareActivitiesTask publicWelfareActivitiesTask = iPublicWelfareActivitiesTaskService.getOne(new QueryWrapper<PublicWelfareActivitiesTask>().lambda()
                .eq(PublicWelfareActivitiesTask::getFlowId, flow.getId()).last("limit 1"));
        PublicWelfareActivities publicWelfareActivities = new PublicWelfareActivities();
        BeanUtils.copyProperties(publicWelfareActivitiesTask, publicWelfareActivities);
        if (iPublicWelfareActivitiesService.save(publicWelfareActivities)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意好人好事
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeGoodThings(Flow flow) {
        GoodThingsTask goodThingsTask = iGoodThingsTaskService.getOne(new QueryWrapper<GoodThingsTask>().lambda()
                .eq(GoodThingsTask::getFlowId, flow.getId()).last("limit 1"));
        GoodThings goodThings = new GoodThings();
        BeanUtils.copyProperties(goodThingsTask, goodThings);
        if (iGoodThingsService.save(goodThings)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 同意学生干部认知
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeJob(Flow flow) {
        JobTask jobTask = iJobTaskService.getOne(new QueryWrapper<JobTask>().lambda()
                .eq(JobTask::getFlowId, flow.getId()).last("limit 1"));
        Job job = new Job();
        BeanUtils.copyProperties(jobTask, job);
        if (iJobService.save(job)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 获取审批详情
     *
     * @param flowId
     * @return
     */
    @Override
    public List<FlowApproveDetailsVo> getApproveDetails(Long flowId) {
        return baseMapper.getFlowApproveDetails(flowId);
    }

    /**
     * 查询已办
     *
     * @param dto
     * @return
     */
    @Override
    public CommonResult<IPage<Flow>> getHasApprove(MyApproveGetDto dto) {
        Page<Flow> page = new Page<>(dto.getCurrentPage(), dto.getPageSize());
        String teacherKey = jwtTokenUtil.getUsernameByRequest(httpServletRequest);
        IPage<Flow> iPage = baseMapper.getPage(page, dto, teacherKey);
        return CommonResult.success(iPage);
    }

    /**
     * 同意德育素质审批
     *
     * @param flow
     * @return
     */
    private CommonResult<String> agreeMoralEducation(Flow flow) {
        MoralEducationTask moralEducationTask = iMoralEducationTaskService.getOne(new QueryWrapper<MoralEducationTask>().lambda()
                .eq(MoralEducationTask::getFlowId, flow.getId()).last("limit 1"));
        MoralEducation moralEducation = new MoralEducation();
        BeanUtils.copyProperties(moralEducationTask, moralEducation);
        if (iMoralEducationService.save(moralEducation)) {
            return CommonResult.success("审批成功");
        }
        return CommonResult.failed("审批失败");
    }

    /**
     * 删除德育素质审批流程
     *
     * @param flowId
     * @return
     */
    private CommonResult<String> delMoralEducation(Long flowId) {
        if (iMoralEducationTaskService.remove(new QueryWrapper<MoralEducationTask>().lambda()
                .eq(MoralEducationTask::getFlowId, flowId))) {
            return CommonResult.success("删除成功");
        }
        return CommonResult.failed("删除失败");
    }
}
